package com.es.www.kyl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.es.www.kyl.bean.req.client.DoExerciseBaseReq;
import com.es.www.kyl.bean.req.client.ExerciseQueryReq;
import com.es.www.kyl.bean.req.client.ExerciseResultReq;
import com.es.www.kyl.bean.res.client.QuestionDetailVO;
import com.es.www.kyl.bean.res.client.QuestionInfoVO;
import com.es.www.kyl.constant.BaseConstants;
import com.es.www.kyl.constant.RedisConstants;
import com.es.www.kyl.domain.*;
import com.es.www.kyl.exception.ResException;
import com.es.www.kyl.factory.RoundFactory;
import com.es.www.kyl.manager.AbstractRoundManager;
import com.es.www.kyl.mapper.*;
import com.es.www.kyl.service.ExerciseService;
import com.es.www.kyl.service.help.ExerciseHelper;
import com.es.www.kyl.service.mapstruct.QuestionMapConstruct;
import com.es.www.kyl.service.mapstruct.UserAnswerLogMapConstruct;
import com.es.www.kyl.util.RedisUtils;
import com.es.www.kyl.util.UserContextHolder;
import com.google.common.collect.Lists;
import javafx.util.Pair;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.es.www.kyl.constant.BusinessResultEnum.NOT_EXIST_WRONG_LIST;

/**
 * @author Estranger
 * @date 2025/8/13
 * description
 */
@Service
@RequiredArgsConstructor
public class ExerciseServiceImpl implements ExerciseService {

	private final UserPracticeStateMapper userPracticeStateMapper;
	private final ExerciseHelper exerciseHelper;
	private final UserAnswerLogMapper userAnswerLogMapper;

	@Override
	public QuestionInfoVO startQuestion(DoExerciseBaseReq req) {
		AbstractRoundManager roundManager = RoundFactory.getRoundManager(BaseConstants.UserPracticeType.COMMON);
		return Objects.isNull(req.getCommonRoundId()) ?
				roundManager.initRound(req, BaseConstants.UserPracticeType.COMMON) :
				roundManager.continueRound(req, BaseConstants.UserPracticeType.COMMON);
	}


	@Override
	public QuestionInfoVO redoQuestion(DoExerciseBaseReq req) {
		AbstractRoundManager roundManager = RoundFactory.getRoundManager(BaseConstants.UserPracticeType.COMMON);
		return roundManager.initRound(req, BaseConstants.UserPracticeType.COMMON);
	}

	@Override
	public QuestionInfoVO doWrongQuestion(DoExerciseBaseReq req) {
		/**
		 * 根据有无错题轮次id判断是首次开始/新的轮次，还是继续做题
		 * 无：
		 *  1. 根据前端传递的普通练习的roundId，查询出所有错题的记录
		 *  2. 生成错题roundId返回
		 *  3. 新增user_practice_state记录
		 * 有：
		 *  1. 根据前端传递的普通练习的roundId，查询出所有错题的记录
		 *  2. 根据错题roundId查询出所有练习错题的记录，判断出做到哪一题了
		 */
		AbstractRoundManager roundManager = RoundFactory.getRoundManager(BaseConstants.UserPracticeType.CORRECTION);
		return Objects.isNull(req.getCorrectionRoundId()) ?
				roundManager.initRound(req, BaseConstants.UserPracticeType.CORRECTION) :
				roundManager.continueRound(req, BaseConstants.UserPracticeType.CORRECTION);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submitQuestionResult(ExerciseResultReq req) {
		UserAnswerLog answerLog = UserAnswerLogMapConstruct.INSTANCE.toUserAnswerLog(req);
		answerLog.setUserId(UserContextHolder.getUserId());
		answerLog.setCreateBy(UserContextHolder.getUserId());
		answerLog.setCreateTime(new Date());
		userAnswerLogMapper.insertSelective(answerLog);
		//更新用户练习状态
		UserPracticeState userPracticeState = userPracticeStateMapper.selectOne(new LambdaQueryWrapper<UserPracticeState>()
				.eq(UserPracticeState::getRoundId, req.getRoundId())
				.eq(UserPracticeState::getCategoryId, req.getCategoryId())
				.eq(UserPracticeState::getUserId, UserContextHolder.getUserId())
				.eq(UserPracticeState::getPracticeType, req.getPracticeType())
		);
		userPracticeState.setLastQuestionId(req.getQuestionId());
		if (req.getLastQuestionFlag()) {
			userPracticeState.setStatus(2);
		}
		userPracticeState.setUpdateBy(UserContextHolder.getUserId());
		userPracticeState.setUpdateTime(new Date());
		userPracticeStateMapper.updateByPrimaryKeySelective(userPracticeState);
	}

	@Override
	public List<QuestionDetailVO> listByQuestionIds(ExerciseQueryReq req) {
		return req.getQuestionIds().stream().map(exerciseHelper::getQuestionDetail).collect(Collectors.toList());
	}

}
